#ifndef __TOYM__BASE__BUFFER_H__
#define __TOYM__BASE__BUFFER_H__

#include <vector>
#include <string>
#include "Base/noncopyable.h"

namespace toym
{

class Buffer: noncopyable {
public:
    Buffer(std::size_t sz = s_defaultSize);

    // 默认生成的移动构造函数可以且足够
    // 默认生成的移动赋值函数可以且足够

    // 获取当前缓冲区中有多少数据
    std::size_t size() const {
        return m_readEnd - m_readStart;
    }

    // 获取缓冲区后面还有多少数据可用
    std::size_t availableSize() const {
        return m_buf.size() - m_readEnd;
    }

    // 在缓冲区后面添加数据
    void append(const char* msg, std::size_t sz);
    void append(const std::string& msg);

    // 在缓冲区前面添加数据
    void prepend(const char* msg, std::size_t sz);
    void prepend(const std::string& msg);

    // 获取指向缓冲区最前面的指针
    char* peek() {
        return curStartAddr();
    };

    // 获取指向已读缓冲区尾的指针
    char* getTail() {
        return curEndAddr();
    }

    // 读取数量
    void read(std::size_t sz);

    // 调整尾指针
    void adjustEnd(int sz) {
        m_readEnd += sz;
    }

    // 读取全部
    void readAll() {
        m_readStart = m_readEnd = s_defaultPrependSize;
    }

    // 读取全部作为string返回
    std::string readAsString();

private:
    char* curStartAddr() {
        return m_buf.data() + m_readStart;
    }

    char* curEndAddr() {
        return m_buf.data() + m_readEnd;
    }

    char* defaultStartAddr() {
        return m_buf.data() + s_defaultPrependSize;
    }

    static
    std::size_t getSize(std::size_t cur, std::size_t needed) {
        return std::max(cur<<1, needed);
    }

    std::vector<char> m_buf;
    std::size_t m_readStart;
    std::size_t m_readEnd;
    static const std::size_t s_defaultSize = 256;
    static const std::size_t s_defaultPrependSize = 8;
};

} // namespace toym


#endif //__TOYM__BASE__BUFFER_H__